package com.example.mapstuct.convert;

import com.example.mapstuct.entity.Order;
import com.example.mapstuct.entity.User;
import com.example.mapstuct.enums.SexEnum;
import com.example.mapstuct.pojo.dto.UserDTO;
import com.example.mapstuct.pojo.vo.AddSexUserVO;
import com.example.mapstuct.pojo.vo.OrderVO;
import com.example.mapstuct.pojo.vo.UserVO;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

/**
 * 基本使用
 *
 * @author Lisicheng
 */
// 构建方式1
@Mapper(componentModel = "spring", imports = {LocalDateTime.class, SexEnum.class})
public interface BasicConvert {

    /**
     * 构建方式2
     */
    BasicConvert INSTANCE = Mappers.getMapper(BasicConvert.class);

    /**
     * 基本使用
     *
     * @param user 源对象
     * @return 转换对象
     */
    UserVO userToUserVO(User user);

    /**
     * 属性名不相同
     *
     * @param user 源对象
     * @return 转换对象
     */
    @Mapping(source = "createTime", target = "registrationTime")
    UserVO notFiledNameToUserVO(User user);

    /**
     * 为属性设置常量值
     *
     * @param user 源对象
     * @return 创建对象
     */
    @Mapping(target = "name", constant = "小红")
    UserVO constant(User user);

    /**
     * 忽略字段转换
     *
     * @param user 源对象
     * @return 转换对象
     */
    @Mappings({
            @Mapping(target = "sex", ignore = true),
            @Mapping(target = "id", ignore = true)
    })
    AddSexUserVO ignore(User user);

    /**
     * 原字段值为null，设置默认值
     *
     * @param user 源对象
     * @return 转换对象
     */
    @Mapping(target = "id", defaultValue = "1")
    UserVO defaultValue(User user);

    /**
     * 时间格式化为字符串
     *
     * @param dateTime localdatetime
     * @return 转换对象
     */
    @Mapping(target = "time", source = "dateTime", dateFormat = "yyyy-MM-dd")
    UserDTO localDateTimeFormat(LocalDateTime dateTime);

    /**
     * 时间格式化为字符串
     *
     * @param dateTime date
     * @return 转换对象
     */
    @Mapping(target = "time", source = "dateTime", dateFormat = "yyyy-MM-dd")
    UserDTO dateFormat(Date dateTime);

    /**
     * 将数字格式化
     *
     * @param order 源对象
     * @return 转换对象
     */
    @Mapping(target = "price", source = "price", numberFormat = "0.00")
    OrderVO numberFormat(Order order);

    /**
     * 多参数转换
     *
     * @param user             源对象
     * @param registrationTime 注册时间
     * @return 转换对象
     */
    @Mapping(source = "registrationTime", target = "registrationTime")
    UserVO doubleFiledToUserVO(User user, LocalDateTime registrationTime);

    /**
     * 更新对象
     *
     * @param user   源对象
     * @param userVO 被更新
     */
    void updateUserVO(User user, @MappingTarget UserVO userVO);

    /**
     * 自定义表达式转换
     * <p>
     * 需要在@Mapper中加入 imports = {LocalDateTime.class, SexEnum.class}
     *
     * @param user 源对象
     * @return 转换对象
     */
    @Mapping(target = "sex", expression = "java(SexEnum.getSexEnumByCode(user.getSex()))")
    AddSexUserVO customExpressionToAddSexUserVO(User user);

    /**
     * 自定义函数转换
     * 1. 根据目标字段类型（也就是函数返回值）
     * 2. 根据参数长度（等于1），类型（会做基本转换）
     * 3. 匹配本类的自定义函数
     *
     * @param user 源对象
     * @return 转换对象
     */
    @Mapping(target = "sex", source = "sex")
    AddSexUserVO customFunctionToAddSexUserVO(User user);

    /**
     * 构建性别枚举
     *
     * @param sex 性别code
     * @return 性别枚举
     */
    default SexEnum buildSexEnum(int sex) {
        return SexEnum.getSexEnumByCode(sex);
    }
}
